import { Ref, nextTick } from 'vue'
import { cloneDeep } from 'lodash'
import { FilterItem, swapIndex } from '@/components'
import { setLocal, getLocal, reomveLocal } from './local'

/**
 * 自定义Table设置 
 * @param Table_ref Table Dom引用 用于获取Dom元素进行动画
 * @param sourceList_ref  原始数据（包含children树形结构）
 * @returns 
 */
export const useFilterCustom = (Table_ref: Ref, sourceList_ref: Ref<FilterItem[]>) => {

  // Table Dom引用
  const TableRef: Ref = Table_ref
  // 原始数据
  const sourceListRef: Ref<FilterItem[]> = sourceList_ref

  /**
   * 是否禁用 [ 上移 | 下移 | 置顶 | 置底 ] 操作
   * @param item 
   * @returns 
   */
  const isDisabledMove = (index:number) => {
    const list = sourceListRef.value

    // 禁用的操作集合
    const disabledMap = {
      up: false,      // 上移
      down: false,    // 下移
      top: false,     // 置顶
      bottom: false,  // 置底
    }

    if (index === 0) {
      disabledMap.top = true
      disabledMap.up = true
    } else if (index === list.length - 1) {
      disabledMap.bottom = true
      disabledMap.down = true
    }

    return disabledMap
  }



  /**
   * 表格行Dom移动动画
   * @param item1 
   * @param item2 
   * @param type 
   * @returns 
   */
  const moveRowElement = (itemList_1: any[], itemList_2: any[], type: 'up' | 'down' | 'top' | 'bottom') => {

    const itemTop_1 = itemList_1[0].offsetTop
    const itemTop_2 = itemList_2[0].offsetTop
    // 判断上移 | 下移 的list
    const upList   = itemTop_1 > itemTop_2 ? itemList_1 : itemList_2
    const downList = itemTop_1 < itemTop_2 ? itemList_1 : itemList_2
    const allList = [...itemList_1, ...itemList_2]
    allList.forEach(item=>{
      item.style.transition = 'transform 0.5s ease-in-out'
      item.style.zIndex = '10'
    })
    if (type === 'up' || type === 'top') {
      downList.forEach(item=>{
        item.style.transitionDelay = '0.2s'
        item.style.zIndex = '5'
      })
    } else {
      upList.forEach(item=>{
        item.style.transitionDelay = '0.2s'
        item.style.zIndex = '5'
      })
    }

    const upTop = upList[0].offsetTop
    const downTop = downList[0].offsetTop
    const upHeight = upList.reduce((total, item) => total + item.offsetHeight, 0)
    const downHeight = downList.reduce((total, item) => total + item.offsetHeight, 0)
    if (type === 'top') {
      upList.forEach(item=>{
        item.style.transform = `translateY(${-(Math.abs(upTop - downTop))}px)`
      })
      return 
    }
    if (type === 'bottom') {
      downList.forEach(item=>{
        item.style.transform = `translateY(${(Math.abs((upTop + upHeight) - (downTop + downHeight)))}px)`
      })
      return 
    }

    // 需要2组元素都移动的
    upList.forEach(item=>{
      item.style.transform = `translateY(${-downHeight}px)`
    })
    downList.forEach(item=>{
      item.style.transform = `translateY(${upHeight}px)`
    })
  }

  
  // 清除样式
  const clearStyle = (tableRowElList) => {
    for (let index = 0; index < tableRowElList.length; index++) {
      const element = tableRowElList[index]
      element.removeAttribute('style')
      element.classList.add('move')
    }
  }


  /**
   * 上移
   * @param item 
   * @param rowIndex 页面视图Dom元素数组下标（扁平化后的数组）
   * @param 步长移动几行 默认1 
   */
  const moveUp = (rowIndex: number, step=1) => {
    const list = sourceListRef.value
    // 获取DOM 用于动画
    const tableRowElList: any[] = TableRef.value.$el.querySelectorAll('.el-table__row')
    const currentElList = [ tableRowElList[rowIndex] ]
    const targetElList = [...tableRowElList].slice(rowIndex - step, rowIndex)
    moveRowElement(currentElList, targetElList, 'up')

    setTimeout(() => {
      if (rowIndex - step >= 0) {
        swapIndex(list, rowIndex, rowIndex - step)
      }
      clearStyle(tableRowElList)
    }, 500)
  }


  /**
   * 下移
   * @param item 
   * @param rowIndex 页面视图Dom元素数组下标（扁平化后的数组）
   * @param 步长移动几行 默认1 
   */
  const moveDown = (rowIndex: number, step=1) => {
    const list = sourceListRef.value
    // 获取DOM 用于动画
    const tableRowElList = TableRef.value.$el.querySelectorAll('.el-table__row')
    const currentElList = [ tableRowElList[rowIndex] ]
    const targetElList = [...tableRowElList].slice(rowIndex, rowIndex + step)
    moveRowElement(currentElList, targetElList, 'down')

    setTimeout(() => {
      if (rowIndex + step <= list.length - 1) {
        swapIndex(list, rowIndex, rowIndex + step)
      }
      clearStyle(tableRowElList)
    }, 500)
  }


  /**
   * 移动到顶部
   * @param item 
   * @param rowIndex 页面视图Dom元素数组下标（扁平化后的数组）
   */
  const moveTop = (rowIndex) => {
    const list = sourceListRef.value
    // 获取DOM 用于动画
    const tableRowElList = TableRef.value.$el.querySelectorAll('.el-table__row')
    const currentElList = [ tableRowElList[rowIndex] ]
    const targetElList = [ tableRowElList[0] ]
    moveRowElement(currentElList, targetElList, 'top')

    setTimeout(() => {
      const [temp] = list.splice(rowIndex, 1)
      nextTick(() => {
        list.splice(0, 0, temp)
        clearStyle(tableRowElList)
      })
    }, 500)
  }


  /**
   * 移动到底部
   * @param item 
   * @param rowIndex 页面视图Dom元素数组下标（扁平化后的数组）
   */
  const moveBottom = (rowIndex) => {
    const list = sourceListRef.value
    // 获取DOM 用于动画
    const tableRowElList = TableRef.value.$el.querySelectorAll('.el-table__row')
    const currentElList = [ tableRowElList[rowIndex] ]
    const targetElList = [ tableRowElList[list.length - 1] ]
    moveRowElement(currentElList, targetElList, 'bottom')

    setTimeout(() => {
      const [temp] = list.splice(rowIndex, 1)
      nextTick(() => {
        list.push(temp)
        clearStyle(tableRowElList)
      })
    }, 500)
  }

  return {
    isDisabledMove,
    moveUp,
    moveDown,
    moveTop,
    moveBottom
  }
}



/**
 * 获取key
 * @param item 
 */
const getItemkey = (item:FilterItem): string => {
  return item.label ?? (typeof item.prop ===  'string' ? item.prop : item.prop[0])
}

export type FilterCustomType = {
  // isShowAll是否展开展示所有搜索条件 默认值
  isShowAll: boolean
  // showRow展示行数 默认值
  showRow: number
  // Filter搜索条件
  filters: FilterItem[]
}

type FilterCustomLocalConfigType = {
  // isShowAll是否展开展示所有搜索条件 默认值
  isShowAll: boolean
  // showRow展示行数 默认值
  showRow: number
  // Filter搜索条件唯一标识
  keys: string[]
}

// 设置初始Filter本地数据
export const getFilterCustomConfig = (customeId: string, customConfig: FilterCustomType): FilterCustomType => {
  const { isShowAll, showRow, filters:sourceFilters } = customConfig
  const localConfig: FilterCustomLocalConfigType = getLocal('FilterConfig:'+customeId)
  if (!localConfig) {
    return { isShowAll, showRow, filters:cloneDeep(sourceFilters) }
  }
  const keys = localConfig.keys
  const filters = cloneDeep(sourceFilters)

  let newFilters:FilterItem[] = keys.map(key => {
    const index = filters.findIndex(item => key === getItemkey(item))
    if (index !== -1) {
      const [item] = filters.splice(index, 1)
      return item
    }
    return null
  }).filter(Boolean)

  // 搜索条件可能存在新增/删除 存在没匹配上的Filter
  if (filters.length != 0) {
    // 直接重置
    removeCustomConfig('FilterConfig:'+customeId)
    return { isShowAll, showRow, filters:cloneDeep(sourceFilters) }
    // 将没匹配到的Filter放后面 
    // newFilters = [...newFilters, ...filters]
  }
  return { isShowAll:localConfig.isShowAll, showRow:localConfig.showRow, filters:newFilters }
}

// 设置初始Filter本地数据
export const setFilterCustomConfig = (customeId: string, customConfig: FilterCustomType) => {
  const { isShowAll, showRow, filters:sourceFilters } = customConfig
  const keys: string[] = sourceFilters.map(getItemkey).filter(Boolean)
  const localConfig: FilterCustomLocalConfigType = { isShowAll, showRow, keys }
  setLocal('FilterConfig:'+customeId, localConfig)
}

// 删除Filter本地数据
export const removeCustomConfig = (customeId: string) => {
  reomveLocal('FilterConfig:'+customeId)
}
